package com.ruoyi.project.system.service.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.domain.SmIncome;
import com.ruoyi.project.system.domain.SmPay;
import com.ruoyi.project.system.domain.vo.PayVo;
import com.ruoyi.project.system.mapper.SmIdentityMapper;
import com.ruoyi.project.system.mapper.SmIncomeMapper;
import com.ruoyi.project.system.mapper.SmPayMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.project.system.service.ISmPayService;
import com.ruoyi.project.system.service.ISmProductService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.ruoyi.common.constant.CacheConstants.UPGRADE_KICKBACK;
import static com.ruoyi.framework.web.domain.AjaxResult.error;
import static com.ruoyi.framework.web.domain.AjaxResult.success;

/**
 * 支付Service业务层处理
 */
@Slf4j
@Service
public class SmPayServiceImpl implements ISmPayService {

    @Autowired
    private ISmProductService iSmProductService;

    @Autowired
    private SmPayMapper smPayMapper;

    @Autowired
    private SmIncomeMapper smIncomeMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SmIdentityMapper smIdentityMapper;

    @Autowired
    private RedisCache redisCache;

    @Value("${back-domain}")
    private String backDomain;

    @Value("${front-domain}")
    private String frontDomain;

    @Override
    public JSONObject zhifuFM(SmPay sm, String path) throws IOException {
        String merchantNum = "501893922617180160";             // 商户号
        String secretKey = "b2a65b1c001c097e717ea2b48a24457a";  // 商户密钥
        String sign = merchantNum + sm.getOrderNo() + sm.getPricing() + backDomain + secretKey;
        sign = Md5Utils.hash(sign);                             // md5签名
        Map<String, String> paramMap = new HashMap<>();         // post请求的参数
        paramMap.put("merchantNum", merchantNum);
        paramMap.put("orderNo", sm.getOrderNo());
        paramMap.put("amount", sm.getPricing().toString());
        paramMap.put("notifyUrl", backDomain);     // 填写您的接收支付成功的异步通知地址
        paramMap.put("returnUrl", frontDomain + path);
        paramMap.put("payType", sm.getPayType());  // MGZ TODO 2025/3/25:支付方式
        paramMap.put("sign", sign);
        paramMap.put("subject", sm.getType());
        log.info("支付请求参数：" + paramMap);
        String result;
        JSONObject ret = new JSONObject();
        String paramStr = StringUtils.toParams(paramMap);
        CloseableHttpClient httpclient = HttpClientBuilder.create().build();
        HttpPost httpost = new HttpPost("http://api-albd2vor5wqo.zhifu.fm.it88168.com/api/startOrder?" + paramStr); // 设置响应头信息
        String userAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36";
        httpost.setHeader("User-Agent", userAgent);     //防止被防火墙拦截 Apache httpclient
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(1000).setSocketTimeout(5000).build();
        httpost.setConfig(requestConfig);

//        return JSONObject.parseObject("{\"success\":true,\"msg\":\"success\",\"code\":200,\"timestamp\":1742923519942,\"data\":{\"id\":\"498753173364817920\",\"payUrl\":\"https://page-albd2vor5wqo.zhifu.fm.it88168.com/apiPay?orderNo=498753173364817920\"}}");

        HttpResponse retResp = httpclient.execute(httpost);
        result = EntityUtils.toString(retResp.getEntity(), "UTF-8");
        if (result.startsWith("{")) { //为了您的业务健壮性，建议简单判断或者增加下容错逻辑
            ret = JSONObject.parseObject(result);
        } else {
            ret.put("code", "error");
            ret.put("result", result);
            ret.put("msg", "发起支付订单失败，接口返回信息异常");
        }
        return ret;
    }

    @Override
    public AjaxResult upgradePay(SmPay smPay) {
        // 1. 写入支付订单
        this.insertSmPay(smPay);
        // 2. 计算写入分成
        this.calculateUpgradeIncome(smPay);
        // 3. 发起支付
        try {
            JSONObject payInfo = this.zhifuFM(smPay, "index");
            payInfo.put("orderNo", smPay.getOrderNo());
            return success(payInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return error("发起支付异常！");
        }
    }

    @Override
    public void calculatePromotionIncome(SmPay smPay, Integer productId, Integer roleId) {  // MGZ TODO 2025/4/12:计算查询收益
        // 自己收益
        BigDecimal promotion = iSmProductService.promotionAdd(smPay.getUserId().longValue(), productId, roleId);
        smIncomeMapper.insertSmIncome(new SmIncome(smPay.getUserId(), "1", "自己推广", promotion, smPay.getId().toString(), "promotion"));
        calculateCommonIncome(smPay, productId, roleId);
    }

    @Override
    public void calculateCommonIncome(SmPay smPay, Integer productId, Integer roleId) {
        Long parentId = sysUserMapper.queryParentId(smPay.getUserId().longValue());
        if (roleId == 3) {         // 团队长推广 (上级区域队长收益)
            BigDecimal basePrice = iSmProductService.basePriceAdd(parentId, productId, 2);
            String status = smIdentityMapper.queryEffectiveSmIdentity(parentId, "region") != null ? "1" : "-1";
            smIncomeMapper.insertSmIncome(new SmIncome(parentId.intValue(), status, "队长推广", basePrice, smPay.getId().toString(), "captain-region"));
        } else if (roleId == 4) {  // 团员推广 (上级团队长/区域队长收益)

            Integer roleId_ = sysUserMapper.queryRoleId(parentId);
            if (roleId_ == 2) {
                BigDecimal basePrice = iSmProductService.basePriceAdd(parentId, productId, 2);
                String status = smIdentityMapper.queryEffectiveSmIdentity(parentId, "region") != null ? "1" : "-1";
                smIncomeMapper.insertSmIncome(new SmIncome(parentId.intValue(), status, "队员推广", basePrice, smPay.getId().toString(), "member-region"));
            } else {
                BigDecimal basePrice = iSmProductService.basePriceAdd(parentId, productId, 3);
                String status = smIdentityMapper.queryEffectiveSmIdentity(parentId, "captain") != null ? "1" : "-1";
                smIncomeMapper.insertSmIncome(new SmIncome(parentId.intValue(), status, "队员推广", basePrice, smPay.getId().toString(), "member-captain"));
                Long parentId_ = sysUserMapper.queryParentId(parentId);
                if (parentId_ == null) {
                    return;
                }
                BigDecimal basePrice_ = iSmProductService.basePriceAdd(parentId_, productId, 2);
                String status_ = smIdentityMapper.queryEffectiveSmIdentity(parentId, "region") != null ? "1" : "-1";
                smIncomeMapper.insertSmIncome(new SmIncome(parentId_.intValue(), status_, "队员推广", basePrice_, smPay.getId().toString(), "member-region"));
            }
        }
    }

    public void calculateUpgradeIncome(SmPay smPay) {
        BigDecimal kickback = redisCache.getCacheObject(UPGRADE_KICKBACK + smPay.getRemark());
        BigDecimal income = null;
        Long parentId = null;
        String upgradePath = smPay.getRemark();
//        String[] targetPath = smPay.getRemark().split("->");
//        String source = targetPath[0];
//        String target = targetPath[1];
        if ("ordinary->member".equals(upgradePath)) {           // 1. 普通账户 —> 团员
            // upgrade_kickback:ordinary->member
            return;
        } else if ("ordinary->captain".equals(upgradePath)) {   // 2. 普通账户 —> 团队长
            // upgrade_kickback:ordinary->captain
            return;
        } else if ("ordinary->region".equals(upgradePath)) {    // 2. 普通账户 —> 区域队长
            // upgrade_kickback:ordinary->region
            return;
        } else if ("member->captain".equals(upgradePath)) {     // 3. 团员 —> 团队长
            // upgrade_kickback:member->captain
            //  团员给予上级团队长补偿费用
            income = smPay.getPricing().multiply(kickback);
            parentId = sysUserMapper.queryParentId(smPay.getUserId().longValue());
            if (parentId == null)
                return;
        } else if ("member->region".equals(upgradePath)) {      // 4. 团员 —> 区域队长
            // upgrade_kickback:member->region
            // 团员给予上级区域队长补偿费用
            income = smPay.getPricing().multiply(kickback);
            parentId = sysUserMapper.queryParentId(smPay.getUserId().longValue());
            if (parentId == null)
                return;
        } else if ("captain->region".equals(upgradePath)) {     // 5. 团队长 —> 区域队长
            // upgrade_kickback:captain->region
            // 团队长给予上级区域队长补偿费用
            income = smPay.getPricing().multiply(kickback);
            parentId = sysUserMapper.queryParentId(smPay.getUserId().longValue());
            if (parentId == null)
                return;
        }
        smIncomeMapper.insertSmIncome(new SmIncome(parentId.intValue(), "1", "用户升级", income, smPay.getId().toString(), "upgrade"));
    }

    @Override
    @Transactional
    public void paySuccessUpgradeSetUser(SmPay smPay) {
        String target = smPay.getRemark().split("->")[1];
        Integer roleId;
        if ("member".equals(target)) {           // 1. —> 团员
            roleId = 4;
        } else if ("captain".equals(target)) {   // 2. —> 团队长
            roleId = 3;
        } else if ("region".equals(target)) {    // 2. —> 区域队长
            roleId = 2;
        } else {
            log.error("升级异常!");
            return;
        }
        long userId = smPay.getUserId().longValue();
        String areaCode = sysUserMapper.selectUserById(userId).getAreaCode();
        smIdentityMapper.insertSmIdentity(userId, target, areaCode);

        Long parentId = null;
        if (!"region".equals(target)) {
            parentId = smIdentityMapper.querySmIdentityIdByUserId(smPay.getUserId().longValue(), "region");
        }
        sysUserMapper.upgradeUser(smPay.getUserId().longValue(), roleId, parentId);
    }

    /**
     * 查询支付
     *
     * @param id 支付主键
     * @return 支付
     */
    @Override
    public SmPay selectSmPayById(Integer id) {
        return smPayMapper.selectSmPayById(id);
    }

    /**
     * 查询支付列表
     *
     * @param payVo 支付
     * @return 支付
     */
    @Override
    public List<PayVo> selectSmPayList(PayVo payVo) {
        return smPayMapper.selectSmPayList(payVo);
    }

    /**
     * 新增支付
     *
     * @param smPay 支付
     * @return 结果
     */
    @Override
    public int insertSmPay(SmPay smPay) {
        smPay.setCreateTime(DateUtils.getNowDate());
        return smPayMapper.insertSmPay(smPay);
    }

    /**
     * 修改支付
     *
     * @param smPay 支付
     * @return 结果
     */
    @Override
    public int updateSmPay(SmPay smPay) {
        smPay.setUpdateTime(DateUtils.getNowDate());
        return smPayMapper.updateSmPay(smPay);
    }

    /**
     * 批量删除支付
     *
     * @param ids 需要删除的支付主键
     * @return 结果
     */
    @Override
    public int deleteSmPayByIds(Integer[] ids) {
        return smPayMapper.deleteSmPayByIds(ids);
    }
}
